#pragma once
#include<iostream>
#include"../../socket/TcpSocket.hpp"
#include <sys/select.h>
#include<assert.h>
#include<list>
#include<unordered_map>
using namespace std;


class SelectServer
{
    private:
    TcpSocket _tc;
    int tcp_listen_fd; 
    list<int> fd_list;
    unordered_map<int,list<int>::iterator> map;

    public:
    SelectServer()
    {
        _tc.Initialization();
        tcp_listen_fd=_tc.listen_fd();
        fd_list.push_back(tcp_listen_fd);
        map[tcp_listen_fd]=fd_list.begin();
    } 
    void Start()
    {
        while(true)
        {
            fd_set readfds;
            FD_ZERO(&readfds);
            //将fd_list中要关心的fd添加进来
            //遍历fd_list，找到最大值
            int max_fd=0;
            for(int fd:fd_list)
            {
                cout<<fd<<endl;
                FD_SET(fd,&readfds);
                if(fd>max_fd)
                max_fd=fd;
            }
            cout<<"cur max_fd : "<<max_fd<<endl;
            int n=select(max_fd+1,&readfds,nullptr,nullptr,nullptr);//阻塞式等待
            if(n>0)
            {
                HandReadFd(&readfds);
            }
            else
            {
                cerr<<"select error"<<endl;
                break;
            }
        }
    }
    private:
    void HandReadFd(fd_set *readfds)//处理读事件
    {
        //遍历fd_list，在要关心的事件中找到事件就绪的fd
        auto tmp_fd_list=fd_list;
        for(int fd:tmp_fd_list)
        {
            if(FD_ISSET(fd,readfds))
            {
                if(fd==tcp_listen_fd)
                {
                    //接收到了新的连接
                    cout<<"accept new connection..."<<"\n";
                    int new_fd=_tc.AcceptConnection();
                    assert(new_fd!=-1);
                    auto it=fd_list.insert(fd_list.end(),new_fd);
                    map[new_fd]=it;
                }
                else
                {
                    //新的读事件
                    cout<<"收到正常的数据需要读取..."<<"\n";
                    string recv_buf;
                    if(_tc.Read(fd,&recv_buf))
                    cout<<"get: "<<recv_buf<<endl;
                    else//对端关闭或者错误
                    {
                        cout<<"对端关闭"<<"\n";
                        //删除fd_list中的fd
                        auto it=map[fd];
                        map.erase(fd);
                        fd_list.erase(it);
                        close(fd);
                    }
                }
            }

        }
    }
};